<?php

namespace IDock\Insurance\JDAL\Response;

use Exception;
use IDock\Http\Response;
use IDock\IDock\IDockEnums;
use IDock\Insurance\JDAL\JDALEnums;
use IDock\Insurance\JDAL\Request\VehicleQuoteMainRequest;
use IDock\Printer\NonCar\NonCarInquirySinglePrinter;
use IDock\Printer\Premium\PremiumCoveragePrinter;
use IDock\Printer\Premium\PremiumInquiryPrinter;
use IDock\Printer\SpecialClausesPrinter;
use IDock\Visitor\Premium\PremiumInquiryVisitor;

class VehicleQuoteMainResponse extends AllJDALResponse
{

    /*** @var PremiumInquiryVisitor $visitor */
    public $visitor;

    /*** @var PremiumInquiryPrinter $printer */
    public $printer = PremiumInquiryPrinter::class;
    
    public function resolve(): Response
    {
        $isTestResponse = $GLOBALS['testResponse'] ?? '';

        $body = $this->getBody();

        if (!json_decode($body)) {
            $this->setError('返回数据异常');
            return $this;
        }
        $data = json_decode($body, true);

        if ($this->printer and is_string($this->printer)) {
            $this->printer = new $this->printer;
        }
        
        $code = $data['code'] ?? '';
        $desc = $data['desc'] ?? '';
        
        if ($code != '0000') {
            $this->repeatData($desc);

            if($this->printer->repeatInsuredFlg) {
                $this->setCode(200);
                return $this;
            }
            
            $this->setError($desc);
            return $this;
        }
        
        $this->setBody($data);
        
        if ($isTestResponse) {
            $this->setResult($data);
            return $this;
        }

        return $this;
    }

    public function printerInit(): Response
    {
        $this->preRuleHandler();
        
        if($this->printer->repeatInsuredFlg) {
            $this->setCode(200);
            return $this;
        }
        
        if ($this->getError()) {
            return $this;
        }
        
        $this->basePart();
        $this->vehicle();
        $this->coverage();
        $this->specialPromise();
        $this->factorRate();
        $this->taxType();
        $this->noCar();

        return $this;
    }

    /**
     * 生成核保数据
     * @param VehicleQuoteMainRequest $request
     * @return void
     * @throws Exception
     */
    public function bindUnderWritingData(VehicleQuoteMainRequest $request) {
        $this->printer->argc['orderId'] = $request->basePremiumInquiry->orderId;

        $underwritingData = $request->generate();

        $basePart = $this->get('basePart', []);
        $vehicle = $this->get('vehicle', []);

        $underwritingData['basePart']['uwDiscountValue'] = $basePart['uwDiscountValue'] ?? '';
        $underwritingData['basePart']['quoteNo'] = $this->printer->inquiryNo;

        $underwritingData['vehicle']['modelCode'] = $vehicle['modelCode'] ?? '';
        $underwritingData['vehicle']['carAge'] = $vehicle['carAge'] ?? '';
        $underwritingData['vehicle']['carActualValue'] = $vehicle['carActualValue'] ?? '';
        $underwritingData['vehicle']['marketValue'] = $vehicle['marketValue'] ?? '';
        $underwritingData['vehicle']['vehicleStyleUniqueId'] = $vehicle['vehicleStyleUniqueId'] ?? '';

        $underwritingData['drivingAccidentInfo'] = $this->get('drivingAccidentInfo',[]);
        //使用报价返回的险种去核保
        $underwritingData['coverageItemList'] = $this->get('coverageItemList',[]);

        $this->printer->argc['underwritingData'] = $underwritingData;
    }

    private function preRuleHandler()
    {
        $quoteResultCode  = $this->get('quoteResultCode');
        
        if ($quoteResultCode != '0000') {
            $msg = $this->get('prefixRuleHandlerResult')['ruleHandlerResultMsg'] ?? '';
            $this->setError($msg);
        }
    }
    
    private function repeatData($desc = '')
    {
        if (!$desc) {
            $desc = $this->get('desc');
        }
        
        if (preg_match('/交强险[^商业]+终保日期([\d\s:-]+)/u', $desc, $matches)) {
            
            if ($matches[1] ?? '') {
                $ciStartData = date('Y-m-d H:i:s', strtotime($matches[1]));
                $this->printer->repeatInsurePrinter['ciStartData'] = $ciStartData;
                $this->printer->repeatInsuredFlg = true;
                $this->printer->success = false;
                
                $this->printer->repeatMessage = $desc;
            }
        }
        
        //if (preg_match('/终保日期：([\d\s:-]+)/', $desc, $matches)) {
        //    if ($matches[1] ?? '') {
        //        $biStartData = date('Y-m-d H:i:s', strtotime($matches[1]));
        //        $this->printer->repeatInsurePrinter['biStartData'] = $biStartData;
        //        $this->printer->repeatInsuredFlg = true;
        //    }
        //}
        //
    }
    
    /**
     * 基础信息
     * @return void
     */
    private function basePart()
    {
        $basePart = $this->get('basePart', []);

        $this->printer->inquiryNo = $basePart['quoteNo'] ?? '';

        $this->printer->ciPremiumPrinter->ciStartData = $basePart['ctplEffctiveDate'] ?? '';
        $this->printer->ciPremiumPrinter->ciEndData = $basePart['ctplExpireDate'] ?? '';
        $this->printer->ciPremiumPrinter->ciPremium = $basePart['totalCtplPremium'] ?? '';
        $this->printer->ciPremiumPrinter->ciBasePremium = $basePart['totalCtplBasicPremium'] ?? '';

        $this->printer->biPremiumPrinter->biStartData = $basePart['commEffectiveDate'] ?? '';
        $this->printer->biPremiumPrinter->biEndData = $basePart['commExpireDate'] ?? '';
        $this->printer->biPremiumPrinter->biPremium = $basePart['totalCommPremium'] ?? '';
        $this->printer->biPremiumPrinter->biBasePremium = $basePart['totalCommBasicPremium'] ?? '';
        $this->printer->biPremiumPrinter->biDiscount = $basePart['totalDiscountValue'] ?? '';

        $this->printer->premiumFactorPrinter->VCIFactorAppend('无赔款优待系数级别', 'ClaimAdjustLevel', $basePart['ClaimAdjustLevel'] ?? '');

        $this->printer->premiumFactorPrinter->VCIFactorAppend('自主定价系数', 'selfPricingCoef', $basePart['uwDiscountValue'] ?? '');

        $this->printer->premiumFactorPrinter->VCIFactorAppend('初始建议定价系数', 'initUwDiscountValue', $basePart['initUwDiscountValue'] ?? '');

        $this->printer->premiumFactorPrinter->ComFactorAppend('交通违法系数', 'trafficDiscountValue', $basePart['trafficDiscountValue'] ?? '');

        $this->printer->premiumFactorPrinter->ComFactorAppend('商业险光博风险类别', 'commBillElrType', $basePart['commBillElrType'] ?? '');

        $this->printer->premiumFactorPrinter->ComFactorAppend('交强险光博风险类别', 'ctplBillElrType', $basePart['ctplBillElrType'] ?? '');
    }

    /**
     * 车辆信息
     * @return void
     */
    private function vehicle()
    {
        $vehicle = $this->get('vehicle', []);

        if ($vehicle['commRenewalType'] ?? '' == 1) {
            $this->printer->premiumFactorPrinter->ComFactorAppend('商业险忠诚度', 'BIRenewalType', '续');
        } else {
            if ($this->visitor->getVehicleVisitor()->isNewVehicle) {
                $this->printer->premiumFactorPrinter->ComFactorAppend('商业险忠诚度', 'BIRenewalType', '新');
            } else {
                $this->printer->premiumFactorPrinter->ComFactorAppend('商业险忠诚度', 'BIRenewalType', '转');
            }
        }

        if ($vehicle['ctplRenewalType'] ?? '' == 1) {
            $this->printer->premiumFactorPrinter->ComFactorAppend('交强险忠诚度', 'CIRenewalType', '续');
        } else {
            if ($this->visitor->getVehicleVisitor()->isNewVehicle) {
                $this->printer->premiumFactorPrinter->ComFactorAppend('交强险忠诚度', 'CIRenewalType', '新');
            } else {
                $this->printer->premiumFactorPrinter->ComFactorAppend('交强险忠诚度', 'CIRenewalType', '转');
            }
        }
    }

    /**
     * 险种
     * @return void
     */
    private function coverage()
    {
        $coverageItemList = $this->get('coverageItemList', []);

        foreach ($coverageItemList as $kind) {

            //交强险
            if ($kind['coverageCode'] == 'CTPL') {
                continue;
            }

            $coverage = new PremiumCoveragePrinter();
            $coverage->coverageCode = array_search($kind['coverageCode'], JDALEnums::$coverageCode);
            $coverage->coverageName = IDockEnums::$coverageCode[$coverage->coverageCode] ?? '';
            $coverage->premium = $kind['premium'] ?? '';
            $coverage->basePremium = $kind['pureRiskPremium'] ?? '';
            $coverage->amount = $kind['sumLimit'] ?? '';
            
            if ($this->visitor->isNewEnergy) {
                $coverage->coverageCode = 'C1' . substr($coverage->coverageCode, 2, 4);
                $coverage->coverageName = IDockEnums::$coverageCode[$coverage->coverageCode];
            }

            //乘客
            if ($kind['coverageCode'] == '') {
                $coverage->unitAmount = $coverage->amount / ($this->visitor->getVehicleVisitor()->vehicleSeat - 1);
            }

            //服务次数
            if (in_array($kind['coverageCode'], ['ERRC', 'ESCC', 'EDSC', 'ECSC'])) {
                $coverage->serviceTimes = $kind['sumLimit'] ?? '';
                $coverage->premium = '0';
            }

            $this->printer->coverageListAppend($coverage);
        }
    }

    /**
     * 特约
     * @return void
     */
    private function specialPromise()
    {
        $specialPromiseInfoList = $this->get('specialPromiseInfoList', []);

        foreach ($specialPromiseInfoList as $value) {

            $specialClausesPrinter = new SpecialClausesPrinter();
            $specialClausesPrinter->clauseName = $value['wordings'];
            $specialClausesPrinter->clauseCode = $value['clauseCode'];
            $specialClausesPrinter->clauseContent = $value['wordings'];
            $specialClausesPrinter->autoFlag = '1';
            $specialClausesPrinter->riskType = $value['productLine'] == '701' ? 'TCI' : 'VCI';//交强险固定特约
            $specialClausesPrinter->argc['productLine'] = $value['productLine'];

            $this->printer->specialClausesAppend($specialClausesPrinter);
        }
    }

    /**
     * 浮动系数
     * @return void
     */
    private function factorRate()
    {
        //商业系数
        $commFloatingRate = $this->get('commFloatingRate',[]);

        if ($commFloatingRate) {
            $this->printer->premiumFactorPrinter->VCIFactorAppend('连续承保年数', 'insureYears', $commFloatingRate['insureYears'] ?? '');

            $this->printer->premiumFactorPrinter->VCIFactorAppend('连续承保期间出险次数', 'claimTimes', $commFloatingRate['claimTimes'] ?? '');

            $noClaimAdjustReason = $commFloatingRate['noClaimAdjustReason'] ?? '';

            if ($noClaimAdjustReason) {
                $this->printer->premiumFactorPrinter->VCIFactorAppend('商业无赔优不浮动原因','BInoClaimAdjustReason',JDALEnums::$BINoCAR[$noClaimAdjustReason]);
            }

            $this->printer->ncdFactor = $commFloatingRate['noCompensationRate'] ?? '';

            $this->printer->premiumFactorPrinter->VCIFactorAppend('商业交通违法系数','BITrafficViolationRate',$commFloatingRate['trafficViolationRate'] ?? '');
        }

        //交强系数
        $ctplFloatingRate = $this->get('ctplFloatingRate',[]);

        if ($ctplFloatingRate) {


            $noClaimAdjustReason = $ctplFloatingRate['noClaimAdjustReason'] ?? '';

            if ($noClaimAdjustReason) {
                $this->printer->premiumFactorPrinter->VCIFactorAppend('交强无赔优不浮动原因','CInoClaimAdjustReason',JDALEnums::$CINoCAR[$noClaimAdjustReason]);
            }

            $this->printer->premiumFactorPrinter->VCIFactorAppend('交强交通违法系数','CITrafficViolationRate',$commFloatingRate['trafficViolationRate'] ?? '');
        }

    }

    /**
     * 车船税
     * @return void
     */
    private function taxType()
    {
        $vehicleTaxationPlatform = $this->get('vehicleTaxationPlatform',[]);

        $taxAmount = $vehicleTaxationPlatform['taxAmount'] ?? '';

        if ($vehicleTaxationPlatform and $taxAmount) {
            $this->printer->carTaxPrinter->carShipTax = $taxAmount['sumTax'] ?? '';
            $this->printer->carTaxPrinter->thisYearTax = $taxAmount['annualTaxDue'] ?? '';
            $this->printer->carTaxPrinter->overdue = $taxAmount['sumOverdue'] ?? '';
            $this->printer->carTaxPrinter->payBackTax = $taxAmount['sumTaxDefault'] ?? '';

        }
    }

    private function noCar()
    {
        $drivingAccidentInfo = $this->get('drivingAccidentInfo',[]);

        if (!$this->visitor->getNonCarInquiryVisitor() or !$drivingAccidentInfo) {
            return;
        }

        $this->printer->nonCarInquiryPrinter->loadVisitor($this->visitor->getNonCarInquiryVisitor()->getNonCarList());

        /*** @var $nonCarInquirySinglePrinter NonCarInquirySinglePrinter */
        $nonCarInquirySinglePrinter = $this->printer->nonCarInquiryPrinter->nonCarInquirySingleList[0];

        $nonCarInquirySinglePrinter->premium = $drivingAccidentInfo['premium'] ?? '';
        $nonCarInquirySinglePrinter->inquiryNo = $drivingAccidentInfo['quoteNo']??'';

        $this->printer->nonCarInquiryPrinter->totalPremium = $drivingAccidentInfo['premium'] ?? '';
    }
}
